<template>
  <el-drawer
    :title="title"
    :visible="visible"
    :direction="direction"
    @update:visible="$emit('update:visible', $event)"
    :size="size"
    @closed="$emit('closed')"
    @open="$emit('open')"
    @opened="$emit('opened')"
    class="ele-form-drawer drawer"
    destroy-on-close
    v-bind="{ ...drawerAttrs, zIndex: nextZIndex }"
  >
    <!-- title 插槽 -->
    <template v-slot:title>
      <slot :title="title" name="title"></slot>
    </template>

    <ele-form
      :formDesc="formDesc"
      :formData="formData"
      @input="$emit('input', $event)"
      :isShowBackBtn="isShowBackBtn"
      :isShowCancelBtn="isShowCancelBtn"
      ref="ele-form"
      :visible="visible"
      v-bind="$attrs"
      v-on="$listeners"
    >
      <!-- 默认插槽 -->
      <template v-slot:default>
        <slot></slot>
      </template>

      <!-- 作用域插槽 -->
      <template
        v-for="(formItem, field) of formDesc"
        v-slot:[field]="{ formData, props }"
      >
        <slot
          :data="formData[field]"
          :desc="formItem"
          :field="field"
          :formData="formData"
          :name="field"
          :props="props"
          :disabled="formItem._disabled"
          :type="formItem._type"
          :options="formItem._options"
        >
          <component
            :disabled="formItem._disabled"
            :desc="formItem"
            :is="formItem._type"
            :formData="formData"
            :options="formItem._options"
            :ref="field"
            :readonly="props.readonly"
            :field="field"
            :value="getValue(field)"
            @input="setValue(field, $event)"
          />
        </slot>
      </template>

      <!-- 按钮插槽 -->
      <template v-slot:form-btn="{ btns }">
        <div
          class="footer__btn"
          :style="{ display: showButton ? 'flex' : 'none' }"
        >
          <slot :btns="btns" name="form-btn">
            <el-button
              :key="index"
              @click="btn.click"
              v-bind="btn.attrs"
              v-for="(btn, index) of getBtns(btns)"
            >
              {{ btn.text }}
            </el-button>
          </slot>
        </div>
      </template>
    </ele-form>
  </el-drawer>
</template>

<script>
  import VXETable from 'vxe-table'
  const cloneDeep = require('clone')

  export default {
    inheritAttrs: false,
    name: 'EleFormDrawer',
    model: {
      prop: 'formData',
      event: 'input',
    },
    props: {
      showButton: {
        type: Boolean,
        default: true,
      },
      // 表单数据
      formData: {
        type: Object,
        required: true,
      },
      // 弹窗是否显示
      visible: {
        type: Boolean,
        default: false,
      },
      // 弹框标题
      title: String,
      // 弹窗标题
      size: {
        type: String,
        default: '35%',
      },
      // 方向
      direction: {
        type: String,
        default: 'rtl',
      },
      // 弹窗其它属性
      drawerAttrs: Object,
      // 是否显示返回按钮, 这里是 false
      isShowBackBtn: {
        type: Boolean,
        default: false,
      },
      // 是否显示取消按钮, 这里是 true
      isShowCancelBtn: {
        type: Boolean,
        default: true,
      },
      // 表单项
      formDesc: {
        type: Object,
        required: true,
      },
      // ... 其它属性同 vue-ele-form 组件
    },
    watch: {
      // 当关闭时, 清空数据
      visible: {
        handler(val) {
          if (!val) {
            this.$emit('input', cloneDeep(this.initVal))
          } else {
            this.nextZIndex = VXETable.config.nextZIndex
            this.$nextTick(() => {
              setTimeout(() => {
                this.$refs['ele-form'].$refs.form.clearValidate()
              }, 50)
              this.$nextTick(() => {
                this.$emit('open')
                this.initVal = cloneDeep(this.formData)
              })
            })
          }
        },
        immediate: true,
        deep: true,
      },
    },
    data() {
      return {
        nextZIndex: 20,
        initVal: {},
      }
    },
    methods: {
      getValue(val) {
        if (this.$refs['ele-form']) {
          return this.$refs['ele-form'].getValue(val)
        }
      },
      setValue(field, $event) {
        this.$nextTick(() => {
          this.$refs['ele-form'].setValue(field, $event)
        })
      },
      getBtns(btns) {
        return btns
          .map((item) => {
            item.click.bind(this.$refs.form)
            return item
          })
          .reverse()
      },
    },
  }
</script>

<style lang="scss">
  .drawer {
    overflow: hidden;
    background-image: radial-gradient(transparent 1px, rgba(0, 0, 0, 0.3) 1px);
    background-size: 4px 4px;
    border-radius: 5px;
    backdrop-filter: saturate(50%) blur(4px);
    .el-drawer__header {
      margin-bottom: 0;
    }
    .el-drawer__body {
      display: flex;
      flex-direction: column;
      height: calc(100vh - 62px - 60px);
      overflow: hidden;
      overflow-y: scroll;
      transform: scale(1, 1);
    }
    .footer__btn {
      position: fixed;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 99;
      display: flex;
      justify-content: flex-end;
      padding: 7px 20px;
      background: #fff;
      border-top: 1px solid #eee;
    }
  }
  .ele-form-drawer .el-drawer__body {
    padding: 0 20px;
  }
</style>
